
package com.hlkj.pay.app.merchant.ext.impl.fuyou.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.framework.http.template.OkHttpTemplate;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.FuYouExtConstant;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.FuYouScenePayOrderExtPt;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.constant.FuYouConstant;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouConfig;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouPayH5OrderResultDto;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.utils.SignUtils;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.MerchantUtils;
import com.hlkj.pay.util.OrderCodeUtil;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 条码支付，商户扫用户二维码收款
 * 
 * @author HlpayTeam
 * @date 2024/11/18 13:08
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = FuYouExtConstant.H5_APP)
public class FuYouH5AppPayOrderExtPt extends FuYouSceneCommonPayOrder implements FuYouScenePayOrderExtPt {

    private final OrderCodeUtil orderCodeUtil;
    private final OkHttpTemplate okHttpTemplate;

    @Override
    public void submitChannelPayOrder(ChannelPayOrderContext channelPayOrderContext) {
        ProviderChannelConfigDO providerChannelConfigDO = channelPayOrderContext.getProviderChannelConfigDO();
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        FuYouConfig fuYouConfig = JsonUtils.parseObject(channelConfig, FuYouConfig.class);
        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        FuYouAppChannelParams fuYouAppChannelParams = fuYouAppChannelParams(merchantAppChannelDO);
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("insCd", fuYouConfig.getInsCd());
            params.put("mchntCd", fuYouAppChannelParams.getFuYouId());
            params.put("termId", fuYouAppChannelParams.getTermId());
            params.put("randomStr", System.currentTimeMillis() + "");
            params.put("appId", "wx42c9727eaa151e8b");
            params.put("reservedOrderNo", payOrderDO.getPayOrderNo());
            params.put("amt", MerchantUtils.YuanToFen(payOrderDO.getAmount()).toString());
            params.put("reservedExpireMinute", expireMinute(payOrderDO.getExpiredTime()).toString());
            params.put("sign", SignUtils.getPaySign(params, fuYouConfig));
            log.info("富友H5支付参数:{}", JsonUtils.toJsonString(params));
            String url = h5Domain(channelPayOrderContext.isTest()) + FuYouConstant.MERCHANT_PAY_ORDER_H5;
            String response = okHttpTemplate.post(url, JsonUtils.toJsonString(params),null);
            log.info("富友H5支付返回参数:{}", response);
            // 发起请求
            FuYouPayH5OrderResultDto fuYouPayOrderResultDto = JsonUtils.parseObject(response, FuYouPayH5OrderResultDto.class);
            if ("000000".equals(fuYouPayOrderResultDto.getResultCode())) {
                channelPayOrderContext.setPayInfo(fuYouPayOrderResultDto.getData().getOpenLink());
                channelPayOrderContext.setPayDataType("pay_url");
                // channelPayOrderContext.setChannelOrderNo(fuYouPayOrderResultDto.getReserved_fy_order_no());
                // channelPayOrderContext.setChannelOrderId(fuYouPayOrderResultDto.getReserved_channel_order_id());
            }
            else {
                String respDesc = fuYouPayOrderResultDto.getResultMsg();
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                if (StringUtils.hasText(respDesc)) {
                    channelPayOrderContext.setRemark(respDesc);
                }
                else {
                    channelPayOrderContext.setRemark("富友提交H5支付查询返回错误信息为空,错误码为:" + fuYouPayOrderResultDto.getResultCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("富友提交H5支付请求失败 message:{}", e.getMessage(), e);
            channelPayOrderContext.setRemark("富友提交H5支付请求失败,失败信息" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    @Override
    public void queryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        ProviderChannelConfigDO providerChannelConfigDO = channelPayOrderQueryContext.getProviderChannelConfigDO();
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        FuYouConfig fuYouConfig = JsonUtils.parseObject(channelConfig, FuYouConfig.class);
        PayOrderDO payOrderDO = channelPayOrderQueryContext.getPayOrderDO();
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderQueryContext.getMerchantAppChannelDO();
        FuYouAppChannelParams fuYouAppChannelParams = fuYouAppChannelParams(merchantAppChannelDO);
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("version", "1.0");
            params.put("insCd", fuYouConfig.getInsCd());
            params.put("mchntCd", fuYouAppChannelParams.getFuYouId());
            params.put("termId", fuYouAppChannelParams.getTermId());
            params.put("randomStr", System.currentTimeMillis() + "");
            params.put("orderNo", payOrderDO.getPayOrderNo());
            params.put("sign", SignUtils.getPaySign(params, fuYouConfig));
            params.put("reservedDsc", channelPayOrderQueryContext.getNotifyUrl());
            log.info("富友H5订单查询参数:{}", JsonUtils.toJsonString(params));
            String url = h5Domain(channelPayOrderQueryContext.isTest()) + FuYouConstant.MERCHANT_PAY_ORDER_QUERY_H5;
            String response = okHttpTemplate.post(url, JsonUtils.toJsonString(params),null);
            // 响应报文验签
            log.info("富友H5订单查询返回参数:{}", JsonUtils.toJsonString(response));
            FuYouPayH5OrderResultDto fuYouPayOrderResultDto = JsonUtils.parseObject(response, FuYouPayH5OrderResultDto.class);
            if ("000000".equals(fuYouPayOrderResultDto.getResultCode())) {
                PayOrderDO updartePayOrderDO = new PayOrderDO();
                FuYouPayH5OrderResultDto.DataBean youPayOrderResultDtoData = fuYouPayOrderResultDto.getData();
                switch (youPayOrderResultDtoData.getTransStat()) {
                    case "SUCCESS":
                    case "REFUND":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.SUCCESS.getCode());
                        updartePayOrderDO.setBankMsg("");
                        updartePayOrderDO.setPayAmount(payOrderDO.getAmount());
                        break;
                    case "CLOSED":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CLOSE.getCode());
                    case "USERPAYING":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                        break;
                    case "NOTPAY":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.PAYING.getCode());
                        break;
                    case "REVOKED":
                        updartePayOrderDO.setState(PayOrderEnums.PAY_ORDER_STATUS.CANCEL.getCode());
                        break;
                }
                if (StringUtils.hasText(youPayOrderResultDtoData.getPayTime())) {
                    try {
                        updartePayOrderDO.setSuccessTime(DateUtils.shanghaiDate(youPayOrderResultDtoData.getPayTime()));
                    }
                    catch (Exception e) {
                        log.error("富友H5订单查询返回 时间格式化错误 dateTime:{},message:{}", youPayOrderResultDtoData.getPayTime(), e.getMessage());
                    }
                }
                updartePayOrderDO.setChannelOrderNo(youPayOrderResultDtoData.getFyTraceNo());
                updartePayOrderDO.setChannelOrderId(youPayOrderResultDtoData.getOrderNo());
                channelPayOrderQueryContext.setUpdartePayOrderDO(updartePayOrderDO);
            }
            else {
                String respDesc = fuYouPayOrderResultDto.getResultMsg();
                channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
                if (StringUtils.hasText(respDesc)) {
                    channelPayOrderQueryContext.setRemark(respDesc);
                }
                else {
                    channelPayOrderQueryContext.setRemark("富友H5订单查询返回错误信息为空,错误码为:" + fuYouPayOrderResultDto.getResultCode());
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("富友H5订单查询支付订单请求失败 message:{}", e.getMessage(), e);
            channelPayOrderQueryContext.setRemark("富友H5订单查询支付订单请求失败,失败信息" + e.getMessage());
            channelPayOrderQueryContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessQueryContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }
    }

    @Override
    public void closeChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {

    }

    @Override
    public void queryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {

    }

    @Override
    public void refundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {

    }

    @Override
    public void queryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {

    }

    @Override
    public boolean refundApply(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        return false;
    }

    @Override
    public CommonResult<String> channelOrderCode(ChannelPayOrderContext channelPayOrderContext) {
        FuYouAppChannelParams fuYouAppChannelParams;
        try {
            fuYouAppChannelParams = fuYouAppChannelParams(channelPayOrderContext.getMerchantAppChannelDO());
            if (!StringUtils.hasText(fuYouAppChannelParams.getTermId())) {
                return CommonResult.error(1, "通道终端号为空");
            }
        }
        catch (Exception e) {
            return CommonResult.error(1, "通道参数配置错误");
        }
        // 商户订单号，必须由T+终端号前缀组成，例如,不能重复
        return CommonResult.success(orderCodeUtil.orderNo("T" + fuYouAppChannelParams.getTermId(), 5));
    }


}
